
from time import sleep
from thread import start_new_thread
import thread
import _emulator
import shutil

_locked = False

class Ao_lock:
    """A Symbian active object based synchronization service.
    
    This can be used in the main thread without blocking the handling of UI events. The application should
    not exit while a thread is waiting in Ao_lock. If Ao_lock is called while another wait is in
    progress, an AssertionError is raised.
    """
    def __init__(self):
        global _locked
	
        if _locked == True:
    	    raise AssertionError, "Ao_lock: Another wait is in progress"

    	_locked = True
	
        self._app = _emulator._app
	
    def wait(self):
	"""If the lock has already been signaled, returns immediately. Otherwise blocks in wait for the lock
        to be signaled. 
        
        Only one waiter is allowed, so you should avoid recursive calls to this service.
        wait can only be called in the thread that created the lock object. During the wait, other
        Symbian-active objects are being served, so the UI will not freeze. This may result in the UI
        callback code being run in the context of the thread that is waiting in Ao_lock. This must be
        considered when designing the application logic.
        """
	if self._app is not None:
	    self._wait_ui()
	else:
	    self._wait_no_ui()
	    
    def _wait_no_ui(self):
	global _locked
	
	while _locked:
	    sleep(0.02)
	
    def _wait_ui(self):
        
        global _locked
        pass
        
    def signal(self):
        """Signals the lock. The waiter is released."""
        global _locked
        _locked = False
	
#	if self._app is not None:
 
    
    
class Ao_timer:
    """The rationale for the Ao timer type is that you cannot cancel a pending e32.ao sleep. This is
    problematic if e.g. the user exits an application which is sleeping. In this case a panic would occur
    since the sleep is not cancelled - this is the reason you should avoid using e32.ao sleep and instead
    use the Ao timer with appropriate cancel calls if there is for example a possibility for the user to
    exit the application during a sleep.
    """

    def after(self, interval, callback = None):
        """Sleeps for the given interval without blocking the active scheduler. When the optional callback is
        given, the call to after returns immediately and the callback gets called after interval.
        """
        pass
        
    def cancel(self):
        """Cancels a pending after call."""
        pass
    
    
# ------------------------  Module level functions     ------------------

def ao_yield():
    """Yields to the active scheduler to have ready active objects with priority above normal scheduled
    for running. This has the effect of flushing the eventual pending UI events. Note that the UI
    callback code may be run in the context of the thread that performs an ao_yield. For
    information on active scheduler, see Series 60 SDK documentation.
    """
    if _emulator._app is not None:
 #       _emulator._app.Yield()
        pass
    else:
	#add non UI yeld (if it has sense)
	pass

def ao_sleep(interval, callback = None):
    """Sleeps for the given interval without blocking the active scheduler. When the optional
    callback is given, the call to ao_sleep returns immediately and the callback gets called
    after interval.
    """
    if callback is not None:
#        wx.FutureCall(interval * 1000, callback)
         pass
    else:
        ao_yield()
        sleep(interval)
	
class Ao_callgate:
    def __init__(self, cb):
	self.fn = cb
	self.homeThreadId = thread.get_ident()
	
    def __call__(self):
	if self.homeThreadID == thread.get_ident():
	    self.fn()
	else:
	    self.fn()

def ao_callgate(wrapped_callable):
    """Wraps wrapped_callable into a callable object callgate that can be called in any thread.
    As a result of a call to callgate, wrapped_callable gets called in the context of the thread
    that originally created the callgate. Arguments can be given to the call. This is actually a simple
    wrapping of the Symbian active object facility.
    """
    callgate = Ao_callgate(wrapped_callable)
    return callgate

def drive_list():
    """Returns a list of currently visible drives as a list of Unicode strings '<driveletter>:'"""
    driveletters = [u"c:", u"e:"]
    return driveletters

def file_copy(target_name, source_name):
     """Copies the file source_name to target_name. The names must be complete paths."""
     shutil.copy(source_name, target_name)
 
def in_emulator():
    """Returns 1 if running in an emulator, or 0 if running on a device."""
    return 1

def set_home_time(time):
    """Set the s time to time (see Section 3.5).device"""
    pass

#Astring containing the version number of the Python for Series 60 and some additional information.     
pys60_version = "1.2 final"

#A tuple containing the five components of the Python for Series 60 version number: major,
#minor, micro, release level, and serial.     
pys60_version_info = (1, 2, "final", 0)

#The SDK version with which this Python was compiled (tuple).
#The following values are possible:
# * (1, 2) S60 1st Edition
# * (2, 0) S60 2nd Edition
# * (2, 6) S60 2nd Edition Feature Pack
# * (2, 8) S60 2nd Edition Feature Pack 32
# * (3, 0) S60 3rd Edition
s60_version_info = (3, 0)

def is_ui_thread():
    """Returns True if the code that calls this function runs in the context of the UI thread; 
    otherwise returns False.
    """
    return thread.get_ident() == _emulator._uiThreadID

def start_exe(filename, command, wait = False):
    """Launches the native Symbian OS executable filename (Unicode) and passes it the command
    string. When wait is set, the function synchronously waits for the exit of the executable and
    returns a value that describes the exit type. Possible values are 0 for normal exit and 2 for
    abnormal exit.
    """
    return 2

def start_server(filename):
    """Starts the Python script in file filename (Unicode) as a server in its own process. Note that
    appuifw module is not available to a server script.
    """
    pass

def reset_inactivity():
    """Resets the timers since the user was last active. As a consequence, the device backlight is normally
    turned on when this function is invoked.
    """
    pass

def inactivity():
    """Returns the time in seconds since the user of the device was last active."""
    return 0


def _stdo(file_name):
    pass
